﻿using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using Bluetooth_Fan.HardwareInfo;
using Bluetooth_Fan.DeviceControl;
using System.Diagnostics;
using Bluetooth_Fan.Classes;
using Bluetooth_Fan.MXXX;
using System.IO;
using System.Text;
using System.ComponentModel;
using Encrypt.DES;
using Encrypt.AES;
using Bluetooth_Fan.BluetoothFan.Static_Class;
using System.Collections.Generic;

namespace Bluetooth_Fan
{
    public partial class BleFan_MainForm : Form
    {
        Bluetooth_FanControl mCBlFan_Control = new Bluetooth_FanControl();


        public BleFan_MainForm()     //窗口创建事件
        {
            InitializeComponent();
            //装载转速段值--------------------------------
            for (int i = 0; i < 11; i++)
            {
                string ss = i + "档";
                MOTO0_Phase.Items.Add(ss);
                MOTO1_Phase.Items.Add(ss);
            }

            SERIA_BUTTON.Text = "打开串口";
            MOTO_Control_Init();  //电机0 控制 初始化
            int Index = Baud.Items.IndexOf("115200"); //在列表中找到115200
            Baud.SelectedIndex = Index;

            //加载监听事件
            mCBlFan_Control.EvenChangeConnect += OnEvenChangeConnect;
            mCBlFan_Control.EvenDeChangeStatus += OnEvenDeChangeStatus;
            mCBlFan_Control.EvenDeADCStats += OnEventDeADCStatus;
            mCBlFan_Control.EvenError += OnEvenError;
            //命令及控制 调试
            mCBlFan_Control.EvenDebug += OnPlayDebugString;
            //枚举电脑上的设备名称
            CHardwareInfo.EvenDebug += OnPlayDebugString;

            Scan_serialport();    //扫描串口
            //文件加密 ------------------
            comboBox1.SelectedIndex = 0;

            //测试--------------------------------------------------
        }



        /// <summary>
        /// 获取PC上的串口号 并加入下拉框中
        /// </summary>
        private void Scan_serialport()
        {
            //得到当前电脑串口号数组
            string[] ports = CHardwareInfo.GetPcSerialPortName();
            COMM.Items.Clear();
            if (ports != null)
            {
                Array.Sort(ports);
                COMM.Items.AddRange(ports);
            }

            if (COMM.Items.Count > 0)
            {
                COMM.SelectedIndex = 0;
            }
        }


        /// <summary>
        /// 串口号下拉事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void COMM_DropDown(object sender, EventArgs e)
        {
            Scan_serialport();
        }
        //初始化
        private void MOTO_Control_Init()
        {
            COMM.Enabled = true;    //允许操作串口号
            Baud.Enabled = true;    //允许操作波特率

            ALL_groupBox1.Enabled = false;   //关闭所有控制
            LookVer.Enabled = false;
        }

        private void MOTO0_Control_START()   //开启用户控制
        {
            COMM.Enabled = false;    //不允许操作串口号
            Baud.Enabled = false;    //不允许操作波特率

            ALL_groupBox1.Enabled = true;   //时能所有控制
            LookVer.Enabled = true;
        }

        /// <summary>
        /// 打开串口单击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SERIA_BUTTON_Click(object sender, EventArgs e)
        {

            //如果当前没有连接
            if (mCBlFan_Control.IsDebiceConnect == false)
            {
                mCBlFan_Control.SeriPortName = CHardwareInfo.GetPcSerialPortNameCom(COMM.Text);
                mCBlFan_Control.SeriPortBaudRate = Convert.ToInt32(Baud.Text);
                mCBlFan_Control.IsDebiceConnect = true;  //连接
            }
            else
            {
                mCBlFan_Control.IsDebiceConnect = false;  //断开
            }
        }

        #region 事件及监听

        public event Action<object, byte[]> EventDeADCStatus;
        private void OnEventDeADCStatus(object obj, byte[] Data)
        {
            if (EventDeADCStatus != null)
            {
                EventDeADCStatus(obj, Data);
            }
        }

        /// <summary>
        /// 定义一个显示调试信息的事件
        /// </summary>
        public event Action<string> PlayDebugString;
        /// <summary>
        /// 打印调试信息
        /// </summary>
        /// <param name="str"></param>
        private void OnPlayDebugString(string str)
        {
            if (PlayDebugString != null)
            {
                PlayDebugString(str);
            }
        }


        private void OnEvenChangeConnect(object obj, bool sta)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<object, bool>(OnEvenChangeConnect), obj, sta);
            }
            else
            {
                if (sta == true)  //打开串口成功
                {
                    SERIA_BUTTON.Text = "关闭串口";
                    MOTO0_Control_START();  //允许用户控制   
                }
                else //关闭串口
                {
                    SERIA_BUTTON.Text = "打开串口";
                    MOTO_Control_Init();  //初始化   禁止用户控制
                }
            }
        }

        private void OnEvenDeChangeStatus(object obj, DeviceStatus desta)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<object, DeviceStatus>(OnEvenDeChangeStatus), obj, desta);
            }
            else
            {
                TimeSpan runtime = TimeSpan.FromSeconds(desta.DeviceRuntime);
                //显示系统运行时间
                SYS_RUN_TIME.Text = "系统运行时间 " + runtime;
                PWM0_Val.Value = Math.Abs(desta.mPwmVal[0]);
                MOTO0_PWM_Text.Text = "PWM值：" + desta.mPwmVal[0];
                PWM1_Val.Value = Math.Abs(desta.mPwmVal[1]);
                MOTO1_PWM_Text.Text = "PWM值：" + desta.mPwmVal[1];
                M0_Z.Checked = (desta.mPwmVal[0] >= 0) ? true : false;
                M0_F.Checked = (desta.mPwmVal[0] < 0) ? true : false;
                M1_Z.Checked = (desta.mPwmVal[1] >= 0) ? true : false;
                M1_F.Checked = (desta.mPwmVal[1] < 0) ? true : false;

                runtime = TimeSpan.FromSeconds(desta.DeRunTim[0].EndTime);
                M0_TIME_DS.Text = "定时时间: " + runtime;
                runtime = TimeSpan.FromSeconds(desta.DeRunTim[0].RunTime);
                M0_TIME_YX.Text = "运行时间: " + runtime;

                runtime = TimeSpan.FromSeconds(desta.DeRunTim[1].EndTime);
                M1_TIME_DS.Text = "定时时间: " + runtime;
                runtime = TimeSpan.FromSeconds(desta.DeRunTim[1].RunTime);
                M1_TIME_YX.Text = "运行时间: " + runtime;
            }
        }
        /// <summary>
        /// 错误事件
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="str"></param>
        private void OnEvenError(object obj, string str)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<object, string>(OnEvenError), obj, str);
            }
            else
            {
                MessageBox.Show(str);
                OnPlayDebugString(str);
            }
        }
        #endregion

        /// <summary>
        /// 设置电机0的无极调速值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MOTO0_BUTT_Click(object sender, EventArgs e)
        {
            if (M0_textBox.Text == "")
            {
                return;
            }
            Int16 Val = Convert.ToInt16(M0_textBox.Text, 10);
            Val = M0_Z.Checked ? ((Int16)Math.Abs(Val)) : (Int16)(-Math.Abs(Val));
            mCBlFan_Control.mDe0PwmVal = Val;
        }

        //设置工作时间按键
        private void M0_TIME_bt_Click(object sender, EventArgs e)
        {
            try
            {
                UInt16 Time = Convert.ToUInt16(M0Runtim.Text, 10);
                if (Time > 60000)
                {
                    throw new Exception();
                }
                mCBlFan_Control.mDe0RunTime = Time;
            }
            catch (Exception)
            {
                MessageBox.Show("最大定时时间为 65535 秒");
            }
        }

        /// <summary>
        /// 设置电机0的转速档
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MOTO0_Phase_SelectionChangeCommitted(object sender, EventArgs e)
        {
            Int16 Index = (Int16)MOTO0_Phase.SelectedIndex;
            Index = M0_Z.Checked ? ((Int16)Math.Abs(Index)) : ((Int16)(-Math.Abs(Index)));
            mCBlFan_Control.mDe0PwmValSec = Index;
        }

        /// <summary>
        /// 设置电机1 的无极转速值  M1_textBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MOTO1_SET_Click(object sender, EventArgs e)
        {
            if (M0_textBox.Text == "")
            {
                return;
            }
            Int16 Val = Convert.ToInt16(M1_textBox.Text, 10);
            Val = M1_Z.Checked ? ((Int16)Math.Abs(Val)) : (Int16)(-Math.Abs(Val));
            mCBlFan_Control.mDe1PwmVal = Val;
        }

        /// <summary>
        /// 电机1正转
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M1_Z_Click(object sender, EventArgs e)
        {
            mCBlFan_Control.mDe1Prograde = true;
        }

        /// <summary>
        /// 电机1反转
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M1_F_Click(object sender, EventArgs e)
        {
            mCBlFan_Control.mDe1Prograde = false;
        }

        /// <summary>
        /// 设置电机1工作时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M1_TIME_bt_Click(object sender, EventArgs e)
        {
            try
            {
                UInt16 Time = Convert.ToUInt16(M1Runtim.Text, 10);
                if (Time > 60000)
                {
                    throw new Exception();
                }
                mCBlFan_Control.mDe1RunTime = Time;
            }
            catch (Exception)
            {
                MessageBox.Show("最大定时时间为 60000 秒");
            }
        }

        /// <summary>
        /// 设置电机1的转速档
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MOTO1_Phase_SelectionChangeCommitted(object sender, EventArgs e)
        {
            Int16 Index = (Int16)MOTO1_Phase.SelectedIndex;
            Index = M1_Z.Checked ? ((Int16)Math.Abs(Index)) : ((Int16)(-Math.Abs(Index)));
            mCBlFan_Control.mDe1PwmValSec = Index;
        }

        //  Action<bool> ；
        private void M0_Z_Click_1(object sender, EventArgs e)
        {
            mCBlFan_Control.mDe0Prograde = true;
        }
        private void M0_F_Click(object sender, EventArgs e)
        {
            mCBlFan_Control.mDe0Prograde = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            mCBlFan_Control.AddControlCmm(new CDeviceControlCMM(SYS_USER_COMM_Enum.Rep_SYS_VER, null));
        }

        #region 文本框输入事件  由于约束只能输入数字

        private void M0Runtim_KeyPress(object sender, KeyPressEventArgs e)
        {
            //如果输入的键值不为数字 且不为退格键 则不处理
            if ((char.IsNumber(e.KeyChar) == false) && (e.KeyChar != (char)Keys.Back))
            {
                e.Handled = true;
            }
        }

        private void M0_textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            //如果输入的键值不为数字 且不为退格键 则不处理
            if ((char.IsNumber(e.KeyChar) == false) && (e.KeyChar != (char)Keys.Back))
            {
                e.Handled = true;
            }
        }

        private void M1_textBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            //如果输入的键值不为数字 且不为退格键 则不处理
            if ((char.IsNumber(e.KeyChar) == false) && (e.KeyChar != (char)Keys.Back))
            {
                e.Handled = true;
            }
        }

        private void M1Runtim_KeyPress(object sender, KeyPressEventArgs e)
        {
            //如果输入的键值不为数字 且不为退格键 则不处理
            if ((char.IsNumber(e.KeyChar) == false) && (e.KeyChar != (char)Keys.Back))
            {
                e.Handled = true;
            }
        }
        #endregion




        //--------------------------------
        /// <summary>
        /// 调试信息显示窗口
        /// </summary>
        private DebugForm Debufform;
        private void Debugcheck_CheckedChanged(object sender, EventArgs e)
        {
            if (Debufform.Visible == true)
            {
                Debufform.Hide();
            }
            else
            {
                Debufform.Show();
            }
        }

        private void BleFan_MainForm_Shown(object sender, EventArgs e)
        {
            //实例化  把父窗口传入
            Debufform = new DebugForm(this);
            //添加Lambda表达式   关闭选中  此时会出发变更事件
            Debufform.FormClosing += (obj, err) =>
            {
                Debugcheck.Checked = false;
            };
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog Openfile = new OpenFileDialog();
            Openfile.CheckFileExists = true;
            Openfile.CheckPathExists = true;
            Openfile.FileName = "";
            Openfile.Filter = "所有文件(*.*)|*.*|加密文件(*.mxxx;)|*.mxxx;";
            Openfile.Title = "选择文件";
            if (Openfile.ShowDialog(this) == DialogResult.OK)
            {
                //得到文件名
                string filePath = Openfile.FileName;
                textBox1.Text = filePath;
            }
        }

        /// <summary>
        ///  文件加密按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (File.Exists(textBox1.Text) == false) //检查文件是否存在
            {
                MessageBox.Show("文件不存在", "请重新选择文件", MessageBoxButtons.OK);
                return;
            }
            if ((CHardwareInfo.ToStringHex(textBox3.Text) == null) || CHardwareInfo.ToStringHex(textBox4.Text) == null)
            {
                MessageBox.Show("只能为十六进制且长度必须为偶数", "向量或秘钥输入错误", MessageBoxButtons.OK);
                return;
            }
            byte[] IVBuff = CHardwareInfo.ToStringHex(textBox3.Text);  //得到初始化向量
            byte[] KEYBuff = CHardwareInfo.ToStringHex(textBox4.Text); //得到秘钥值
            bool DES_Handle = true;   //当前是否为DES算法
            if (comboBox1.Text == "DES")
            {
                if ((IVBuff.Length != 8) || ((KEYBuff.Length != 8) && (KEYBuff.Length != 16) && (KEYBuff.Length != 24)))
                {
                    MessageBox.Show("向量固定为8字节，秘钥长度为 8、16、24字节 ", "DES向量或秘钥长度错误", MessageBoxButtons.OK);
                    return;
                }
            }
            else if (comboBox1.Text == "AES")
            {
                DES_Handle = false;
                if ((IVBuff.Length != 16) || ((KEYBuff.Length != 16) && (KEYBuff.Length != 24) && (KEYBuff.Length != 32)))
                {
                    MessageBox.Show("向量固定为16字节，秘钥长度为 16、24、32字节 ", "AES向量或秘钥长度错误", MessageBoxButtons.OK);
                    return;
                }
            }

            SaveFileDialog Savefile = new SaveFileDialog();
            Savefile.FileName = "";
            Savefile.Filter = "加密文件(*.mxxx;)|*.mxxx;|所有文件(*.*)|*.*";
            Savefile.Title = "选择文件";
            if (Savefile.ShowDialog(this) == DialogResult.OK)
            {
                FileStream filestream = File.OpenRead(textBox1.Text);  //得到读文件的数据流
                Debug.WriteLine("文件大小：" + filestream.Length);
                byte[] filedata = new byte[filestream.Length];
                filestream.Read(filedata, 0, filedata.Length);  //读取全部文件数据
                filestream.Close();
                byte[] buff = new byte[1];
                //提供一种把两个或者多个文件拼接在一起的方法
                CMXXXFile.Creation_MxxxFile(ref buff, filedata, richTextBox1.Text); //把自定义数据与文件数据拼接  
                int Err = 0;
                if (DES_Handle)
                {
                    Err = CMY_DES_Encrypt.DES_NoKey_ENC_DEC_CBC(IVBuff, buff, KEYBuff, true);
                }
                else
                {
                    Err = CMY_AES_Encrypt.AES_Encrypt_Decode_CBC(IVBuff, buff, KEYBuff, true) + 0X2000;
                }
                if ((Err == 0) || (Err == 0X2000))
                {
                    //计算CRC
                    UInt32 CRCData = CCRC32_0X04C11DB7.Get_CRC32_ETH_STM32(0XFFFFFFFF, buff);
                    List<byte> bytelist = new List<byte>();
                    bytelist.AddRange(buff);
                    bytelist.AddRange(BitConverter.GetBytes(CRCData));  //把CRC数据写入文件尾 
                    filestream = File.Create(Savefile.FileName);
                    filestream.Write(bytelist.ToArray(), 0, bytelist.Count);
                    filestream.Close();
                    textBox2.Text = Savefile.FileName;
                    MessageBox.Show("加密完成");
                }
                else
                {
                    MessageBox.Show(((Err > 0x2000) ? "AES" : "DES") + "加密失败 ERR:0X" + (Err - 0X2000).ToString("X2"), "错误", MessageBoxButtons.OK);
                }
            }
        }

        /// <summary>
        ///  文件解密按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            if (File.Exists(textBox1.Text) == false) //检查文件是否存在
            {
                MessageBox.Show("文件不存在", "请重新选择文件", MessageBoxButtons.OK);
                return;
            }
            if ((CHardwareInfo.ToStringHex(textBox3.Text) == null) || CHardwareInfo.ToStringHex(textBox4.Text) == null)
            {
                MessageBox.Show("只能为十六进制且长度必须为偶数", "向量或秘钥输入错误", MessageBoxButtons.OK);
                return;
            }
            byte[] IVBuff = CHardwareInfo.ToStringHex(textBox3.Text);  //得到初始化向量
            byte[] KEYBuff = CHardwareInfo.ToStringHex(textBox4.Text); //得到秘钥值
            bool DES_Handle = true;   //当前是否为DES算法
            if (comboBox1.Text == "DES")
            {
                if ((IVBuff.Length != 8) || ((KEYBuff.Length != 8) && (KEYBuff.Length != 16) && (KEYBuff.Length != 24)))
                {
                    MessageBox.Show("向量固定为8字节，秘钥长度为 8、16、24字节 ", "DES向量或秘钥长度错误", MessageBoxButtons.OK);
                    return;
                }
            }
            else if (comboBox1.Text == "AES")
            {
                DES_Handle = false;
                if ((IVBuff.Length != 16) || ((KEYBuff.Length != 16) && (KEYBuff.Length != 24) && (KEYBuff.Length != 32)))
                {
                    MessageBox.Show("向量固定为16字节，秘钥长度为 16、24、32字节 ", "AES向量或秘钥长度错误", MessageBoxButtons.OK);
                    return;
                }
            }
            SaveFileDialog Savefile = new SaveFileDialog();
            Savefile.FileName = "";
            Savefile.Filter = "文本文件(*.txt;)|*.txt;|所有文件(*.*)|*.*;";
            Savefile.Title = "选择文件";
            if (Savefile.ShowDialog(this) == DialogResult.OK)
            {
                FileStream filestream = File.OpenRead(textBox1.Text);  //得到读文件的数据流
                Debug.WriteLine("文件大小：" + filestream.Length);
                byte[] filedata = new byte[filestream.Length];
                filestream.Read(filedata, 0, filedata.Length);  //读取全部文件数据
                filestream.Close();
                UInt32 CRCdata = BitConverter.ToUInt32(filedata, filedata.Length - 4);
                byte[] TempBuff = new byte[filedata.Length - 4];
                Array.Copy(filedata, TempBuff, TempBuff.Length);
                int Err = 0;
                //如果文件长度正确 且CRC正确
                if ((((filedata.Length - 4) % 16) == 0) && (CCRC32_0X04C11DB7.Get_CRC32_ETH_STM32(0XFFFFFFFF, TempBuff) == CRCdata))
                {
                    filedata = new byte[TempBuff.Length];
                    Array.Copy(TempBuff, filedata, filedata.Length); //去掉最后4字节的CRC
                }
                if (DES_Handle)
                {
                    Err = CMY_DES_Encrypt.DES_NoKey_ENC_DEC_CBC(IVBuff, filedata, KEYBuff, false); //解密
                }
                else
                {
                    Err = CMY_AES_Encrypt.AES_Encrypt_Decode_CBC(IVBuff, filedata, KEYBuff, false) + 0X2000; //解密
                }
                if ((Err == 0) || (Err == 0X2000))
                {
                    richTextBox1.Clear(); //清除文本数据

                    byte[] buff = new byte[1];
                    string userstr = string.Empty;
                    //如果是mxxx格式文件数据  则显示 
                    //提供一种把两个或者多个文件拼接在一起的方法
                    if (CMXXXFile.Splitting_MxxxFile(filedata, ref buff, ref userstr) == 0)
                    {
                        richTextBox1.AppendText(userstr);  //显示自定义数据
                    }
                    filestream = File.Create(Savefile.FileName);
                    if (buff != null)
                    {
                        filestream.Write(buff, 0, buff.Length);
                    }
                    filestream.Close();
                    textBox2.Text = Savefile.FileName;
                    MessageBox.Show("解密完成");
                }
                else
                {
                    MessageBox.Show(((Err > 0x2000) ? "AES" : "DES") + "解密失败 ERR:0X" + (Err - 0x2000).ToString("X2"), "错误", MessageBoxButtons.OK);
                }
            }
        }

        /// <summary>
        /// 自定义数据文本框 文本内容发生变化    触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            label9.Text = "字符数:" + Encoding.Default.GetByteCount(richTextBox1.Text);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }

        /// <summary>
        /// 加密算法下拉框 索引值发生了变更 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string StrIv = textBox3.Text;
            string StrKey = textBox4.Text;
            if (comboBox1.Text == "DES")
            {
                textBox3.MaxLength = 8 * 2;   //2个字符为一个字节
                textBox4.MaxLength = 24 * 2;
            }
            else if (comboBox1.Text == "AES")
            {
                textBox3.MaxLength = 16 * 2;
                textBox4.MaxLength = 32 * 2;
            }

            textBox3.Text = StrIv.Substring(0, Math.Min(Encoding.Default.GetByteCount(StrIv), textBox3.MaxLength));
            textBox4.Text = StrKey.Substring(0, Math.Min(Encoding.Default.GetByteCount(StrKey), textBox4.MaxLength));
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            label13.Text = Encoding.Default.GetByteCount(textBox3.Text).ToString();
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {
            label14.Text = Encoding.Default.GetByteCount(textBox4.Text).ToString();
        }
    }
}
